﻿
using System;
using System.Linq;
using System.Windows.Threading;

namespace DrDimsPrivateLib.MqLothub2018WithWPF.MVVMLight
{
    using GalaSoft.MvvmLight.Messaging;
    using GalaSoft.MvvmLight.Command;
    using System.Collections.ObjectModel;
    using System.Windows.Input;

    using LibMQTT.ProtocalIMPL;
    using LibMQTT.TCPServices;

    using MrPoetic.MatLab.Hash;
    using MrPoetic.MatLab;
    using Models;
    using System.Threading.Tasks;

    /* 
    * 根据MVVM设计模式: 在`主进程`启动的时候 
    * WPF视图层通过传入主线程管理器到ViewModel视图模型初始化方法的形式
    * 让每一个WPF页面的编码工作 跳转到 Model层内部进行实现 
    * 然后通过 发送全局消息(MVVMLight工具)到前端去更新UI
    * 开发过程非常艰难 但也只能这样做 才能编写出带用户界面的实时更新的Socket服务端程序 
    */
    internal class TransportViewModel
    {
        // 内核数据结构
        private readonly Dispatcher _UIThread = null;
        internal MqLotBase LegacyDaemon = null;

        // #region MVVMLight 5.1
        public ObservableCollection<InfoNodes> receivingMsgQueue { get; set; }
        public ICommand TouchAction { get; set; }

        static string GetToken
        {
            get
            {
                return  DataMatrix.GenAnyLetters(23);
            }
        }
        static string GetPwd(string key)
        {
            return (key??"123456").ToHashString();
        }

        public TransportViewModel(Dispatcher ProccessTask)
        {
            _UIThread = ProccessTask;
            receivingMsgQueue = new ObservableCollection<InfoNodes>();
            TouchAction = new RelayCommand(TouchActionIMPL);

            // 启动一个定时器(异步) 监听全局日志队列
            LegacyDaemon = new MqLotService(16383, 20);
            var AnyListener = new System.Timers.Timer();
            AnyListener.Elapsed += PingTimerAction;
            AnyListener.AutoReset = true;
            AnyListener.Interval = 200; //200毫秒 监听一次底层数据结构容器
            AnyListener.Start();
        }

        /// 这里只能 启动一个异步线程 等待2秒 然后回主线程 再发消息 
        /// 上层处理UI消息一定是在主线程中 所以2秒以后发消息一定要回主线程
        private void TouchActionIMPL()
        {
            Messenger.Default.Send("用户正在输入...", MainWindow.UISingal);
            Task t2 = new Task(() =>
            {
                _UIThread.Invoke(() =>
                {
                    var rdTitle = GetToken;
                    Console.WriteLine(rdTitle + "|"+ GetPwd("111500"));
                    Messenger.Default.Send(rdTitle, MainWindow.UISingal);
                });
            });
            Task.Delay(2000).ContinueWith(task => t2.Start());
        }
        /// <summary>
        /// 定时器异步监听函数
        /// </summary>
        /// <param name="sender"><b>SysTimer定时器对象</b> </param>
        /// <param name="e">窗体绑定的用户事件</param>
        private void PingTimerAction(object sender, System.Timers.ElapsedEventArgs e)
        {
            var queue = LegacyDaemon.MessageTimeLine.Value;
            if (queue.Any())
            {
                MqPayloadVariable info = queue.LastOrDefault();
                var model = new InfoNodes
                {
                    Which = info.ToString(),
                    What = info["AttachedMsg"],
                    Who = info["ClientID"] + "\n" + info["WillTopic"] + "\n" + info["willMessage"],
                    ByteMatrix = info.SeeBytesMatrix(18),
                };

                _UIThread.Invoke(() =>
                {
                    // 发送全局消息
                    receivingMsgQueue.Add(model);
                    // 异步更新UI
                    Messenger.Default.Send(info, MainWindow.DesignSignal);
                    queue.Dequeue();
                });
            }
        }
    }
}
